package com.aps.server.service;

import com.alibaba.fastjson2.JSON;
import com.aps.common.boot.CoreApplicationContext;
import com.aps.common.code.DistributedSnowflakeIdGenerator;
import com.aps.common.redis.RedisUtils;
import com.aps.common.service.TestGenericService;
import com.aps.server.context.RedisKeyConstant;
import com.aps.server.dto.SchedulingPlanGenerateDto;
import com.aps.server.entity.ApsConstraint;
import com.aps.server.mapper.ApsConstraintMapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * APS约束规则服务类
 * 提供约束规则相关的业务逻辑处理
 */
@Slf4j
@Service
public class ApsConstraintService extends TestGenericService {

    @Resource
    ApsConstraintMapper apsConstraintMapper;


    private static final String CONSTRAINT_DETAILS_TENANT_MAP = "constraint_details_tenant_map_::";
    private static final String CONSTRAINT_DETAILS_CACHE_KEY_PREFIX = "constraint_details_cache_key_::";


    /**
     * 创建约束规则
     *
     * @param apsConstraint 约束规则信息
     * @return 是否创建成功
     */
    public boolean createConstraint(ApsConstraint apsConstraint) {
        // 自动设置租户ID
        if (apsConstraint.getTenantId() == null || apsConstraint.getTenantId().trim().isEmpty()) {
            apsConstraint.setTenantId(getCurrentTenantId());
        }
//        apsConstraint.setId(DistributedSnowflakeIdGenerator.generate20DigitId());
        apsConstraint.setCreateTime(LocalDateTime.now());
        apsConstraint.setUpdateTime(LocalDateTime.now());

        int result = apsConstraintMapper.insert(apsConstraint);
        log.info("创建APS约束规则结果: {}, 约束规则ID: {}, 租户ID: {}", result > 0 ? "成功" : "失败", apsConstraint.getId(), apsConstraint.getTenantId());
        return result > 0;
    }

    /**
     * 根据ID查询约束规则
     *
     * @param id 约束规则ID
     * @return 约束规则信息
     */
    public ApsConstraint getConstraintById(String id) {
        String tenantId = getCurrentTenantId();
        QueryWrapper<ApsConstraint> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id).eq("tenant_id", tenantId);
        ApsConstraint constraint = apsConstraintMapper.selectOne(queryWrapper);

        log.info("查询APS约束规则ID: {}, 租户ID: {}, 结果: {}", id, tenantId, constraint != null ? "找到" : "未找到");
        return constraint;
    }


    //保存约束详情数据
    public boolean saveConstrainByConstrainIdDetails(SchedulingPlanGenerateDto dto){
        if (dto.getBaseParameters().getConstraintInfo().getId() == null
                || dto.getBaseParameters().getConstraintInfo().getId().trim().isEmpty()) {
            throw new RuntimeException("未获取到 约束id，请刷新页面重试");
        }
        String cId = dto.getBaseParameters().getConstraintInfo().getId();
        RedisUtils.setCacheMapValue(getTenantIdMapCacheKey(),cId, JSON.toJSONString(dto));
        return true;
    }

    /**
     * 查询约束详情
     * @param constrainId
     * @return
     */
    public SchedulingPlanGenerateDto getTenantIdMapCacheInfo(String constrainId){
        if(!RedisUtils.hasKey(getTenantIdMapCacheKey())){
            RedisUtils.setCacheMap(constrainId,new HashMap<>());
        }
        return JSON.parseObject((String) RedisUtils.getCacheMapValue(getTenantIdMapCacheKey()
                , constrainId),SchedulingPlanGenerateDto.class);
    }


    private String getTenantIdMapCacheKey(){
        return RedisKeyConstant.getDefaultKey(RedisKeyConstant.BIZ_REDIS_CONSTRAINT_DATA_KEY,getCurrentTenantId());
    }

    //删除对应约束明细缓存
    public void deleteDetailsCacheByConstraintId(String constrainId) {
        RedisUtils.delCacheMapValue(getTenantIdMapCacheKey(),constrainId);
    }

    /**
     * 根据ID和指定租户ID查询约束规则
     *
     * @param id 约束规则ID
     * @param tenantId 租户ID
     * @return 约束规则信息
     */
    public ApsConstraint getConstraintById(String id, String tenantId) {
        QueryWrapper<ApsConstraint> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id).eq("tenant_id", tenantId);

        ApsConstraint constraint = apsConstraintMapper.selectOne(queryWrapper);
        log.info("查询APS约束规则ID: {}, 租户ID: {}, 结果: {}", id, tenantId, constraint != null ? "找到" : "未找到");
        return constraint;
    }

    /**
     * 更新约束规则信息
     *
     * @param apsConstraint 约束规则信息
     * @return 是否更新成功
     */
    public boolean updateConstraint(ApsConstraint apsConstraint) {
        apsConstraint.setUpdateTime(LocalDateTime.now());

        QueryWrapper<ApsConstraint> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", apsConstraint.getId()).eq("tenant_id", apsConstraint.getTenantId());

        int result = apsConstraintMapper.update(apsConstraint, queryWrapper);
        log.info("更新APS约束规则结果: {}, 约束规则ID: {}, 租户ID: {}", result > 0 ? "成功" : "失败", apsConstraint.getId(), apsConstraint.getTenantId());
        return result > 0;
    }

    /**
     * 删除约束规则
     *
     * @param id 约束规则ID
     * @return 是否删除成功
     */
    public boolean deleteConstraint(String id) {
        String tenantId = getCurrentTenantId();
        deleteDetailsCacheByConstraintId(id);
        return deleteConstraint(id, tenantId);
    }

    /**
     * 根据ID和租户ID删除约束规则
     *
     * @param id 约束规则ID
     * @param tenantId 租户ID
     * @return 是否删除成功
     */
    public boolean deleteConstraint(String id, String tenantId) {
        QueryWrapper<ApsConstraint> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id", id).eq("tenant_id", tenantId);

        int result = apsConstraintMapper.delete(queryWrapper);
        log.info("删除APS约束规则结果: {}, 约束规则ID: {}, 租户ID: {}", result > 0 ? "成功" : "失败", id, tenantId);
        return result > 0;
    }

    /**
     * 查询当前租户的约束规则列表
     *
     * @return 约束规则列表
     */
    public List<ApsConstraint> getConstraintsByTenantId() {
        String tenantId = getCurrentTenantId();
        return getConstraintsByTenantId(tenantId);
    }

    /**
     * 根据租户ID查询约束规则列表
     *
     * @param tenantId 租户ID
     * @return 约束规则列表
     */
    public List<ApsConstraint> getConstraintsByTenantId(String tenantId) {
        List<ApsConstraint> constraints = apsConstraintMapper.selectByTenantId(tenantId);
        log.info("根据租户ID查询约束规则列表, 租户ID: {}, 数量: {}", tenantId, constraints.size());
        return constraints;
    }

    /**
     * 分页查询当前租户的约束规则列表
     *
     * @param current 当前页
     * @param size 每页大小
     * @return 分页约束规则列表
     */
    public IPage<ApsConstraint> getConstraintsByTenantIdPage(int current, int size) {
        String tenantId = getCurrentTenantId();
        return getConstraintsByTenantIdPage(current, size, tenantId);
    }

    /**
     * 根据租户ID分页查询约束规则列表
     *
     * @param current 当前页
     * @param size 每页大小
     * @param tenantId 租户ID
     * @return 分页约束规则列表
     */
    public IPage<ApsConstraint> getConstraintsByTenantIdPage(int current, int size, String tenantId) {
        Page<ApsConstraint> page = new Page<>(current, size);
        IPage<ApsConstraint> result = apsConstraintMapper.selectPageByTenantId(page, tenantId);
        log.info("分页查询约束规则列表, 租户ID: {}, 当前页: {}, 每页大小: {}, 总数: {}", tenantId, current, size, result.getTotal());
        return result;
    }

    /**
     * 根据约束名称查询约束规则
     *
     * @param constraintName 约束名称
     * @param tenantId 租户ID
     * @return 约束规则信息
     */
    public ApsConstraint getConstraintByConstraintName(String constraintName, String tenantId) {
        ApsConstraint constraint = apsConstraintMapper.selectByConstraintName(constraintName, tenantId);
        log.info("根据约束名称查询约束规则, 约束名称: {}, 租户ID: {}, 结果: {}", constraintName, tenantId, constraint != null ? "找到" : "未找到");
        return constraint;
    }

    /**
     * 统计租户下的约束规则数量
     *
     * @param tenantId 租户ID
     * @return 约束规则数量
     */
    public Long countConstraintsByTenantId(String tenantId) {
        Long count = apsConstraintMapper.countByTenantId(tenantId);
        log.info("统计租户约束规则数量, 租户ID: {}, 数量: {}", tenantId, count);
        return count;
    }

    /**
     * 批量创建约束规则
     *
     * @param constraints 约束规则列表
     * @return 成功创建的数量
     */
    public int batchCreateConstraints(List<ApsConstraint> constraints) {
        if (constraints == null || constraints.isEmpty()) {
            return 0;
        }

        String tenantId = getCurrentTenantId();
        LocalDateTime now = LocalDateTime.now();

        int successCount = 0;
        for (ApsConstraint constraint : constraints) {
            try {
                if (constraint.getTenantId() == null || constraint.getTenantId().trim().isEmpty()) {
                    constraint.setTenantId(tenantId);
                }
                constraint.setCreateTime(now);
                constraint.setUpdateTime(now);

                int result = apsConstraintMapper.insert(constraint);
                if (result > 0) {
                    successCount++;
                }
            } catch (Exception e) {
                log.error("批量创建约束规则失败, 约束名称: {}", constraint.getConstraintName(), e);
            }
        }

        log.info("批量创建约束规则完成, 总数: {}, 成功: {}", constraints.size(), successCount);
        return successCount;
    }
}
